package controller

import (
	"encoding/json"
	"errors"
	"github.com/e421083458/gorm"
	"github.com/gin-gonic/gin"
	"github.com/gogf/gf/container/gtype"
	"github.com/gogf/gf/util/gconv"
	"rock/customer/dto"
	"rock/customer/initParam"
	"rock/customer/middleware"
	"rock/customer/models"
	"rock/customer/modules/cacheMap"
	"rock/customer/modules/redisModules"
	"rock/customer/modules/taskMap"
	"rock/customer/public"
	"strconv"
	"strings"
	"time"
)

// @Summary 消息列表
// @Description 消息content里面有特殊消息（style：确认消息 question；普通消息 talk 或为空字符串；合并消息 merge），这种情况下，特殊信息存在 extra 字段
// @Tags 会话
// @ID   /messageslist
// @Accept  json
// @Produce  json
// @Param polygon body dto.User true "body"
// @Success 200 {object} middleware.Response{data=dto.ChatMessagePageList} "success"
// @Router /messageslist [post]
func (c *ChatMessageController) messagesList(router *gin.Context) {
	params := &dto.User{}
	if err := params.BindingParams(router); err != nil {
		middleware.ResponseError(router, middleware.PARMAS_ERROR_CODE, err)
		return
	}
	// 查询聊天列表
	ChatMessagePageNew, count, err := messagesList(router, params)
	if err != nil {
		if err.Error() != initParam.DataIsNotExist {
			middleware.ResponseError(router, middleware.DATA_NOT_EXIST, err)
			return
		}
	}
	if ChatMessagePageNew == nil {
		responseData := dto.NullComeBack{
			Page: dto.Page{
				PageNum:  params.PageNum,
				PageSize: params.PageSize,
				Total:    count,
			},
			List: make([]string, 0),
		}
		middleware.ResponseSuccess(router, responseData)
		return
	}
	redisData := dto.ChatMessagePageList{
		Page: dto.Page{
			PageNum:  params.PageNum,
			PageSize: params.PageSize,
			Total:    count,
		},
		ChatMessagePage: ChatMessagePageNew,
	}
	responseData := redisData
	middleware.ResponseSuccess(router, responseData)
}

// @Summary 消息内容
// @Description
// @Tags 会话
// @ID   /messagescontent
// @Accept  json
// @Produce  json
// @Param polygon body dto.User true "body"
// @Success 200 {object} middleware.Response{data=dto.ChatMessagePageList} "success"
// @Router /messagescontent [post]
func (c *ChatMessageController) messagesContent(router *gin.Context) {
	params := &dto.User{}
	if err := params.BindingParams(router); err != nil {
		middleware.ResponseError(router, middleware.PARMAS_ERROR_CODE, err)
		return
	}
	browseCurrent := 0
	id := 0
	if params.IsCustomerClient == 1 {
		//
		browseCurrent = redisInt(router, initParam.BrowseCurrentPrefix + params.GroupId, 0)
		//
		messageUid, err := messageService.MessageByUid(router, BusinessDB, params.MessageUId)
		if err != nil {
			if !errors.Is(err, gorm.ErrRecordNotFound) {
				middleware.ResponseError(router, middleware.INTERNAL_ERROR_CODE, err)
				return
			}
		}
		id = messageUid.ID
	}
	messageContentNew := make([]dto.MessageContent, 0)
	messageContent, count, err := messageService.MessageContent(router, BusinessDB, params.PageNum, params.PageSize, params.GroupId, browseCurrent, id)
	if err != nil {
		//sql: no rows in result set
		if !errors.Is(err, gorm.ErrRecordNotFound) {
			middleware.ResponseError(router, middleware.PARMAS_ERROR_CODE, err)
			return
		}
	}
	tipsShow := 0
	tipsIsShow := 0
	robotId := ""
	adminName := ""
	if params.IsCustomerClient == 1 && params.PageNum == 1 {
		tipsShow = 1
		groupRobot, err := groupService.GroupRobot(router, BusinessDB, params.GroupId)
		if err != nil {
			dealRequestError(router, err)
			return
		}
		robotId = initParam.RobotTarget + strconv.Itoa(groupRobot.ID)
		groupMemberAdmin, err := groupService.GroupMemberAdmin(router, BusinessDB, params.GroupId)
		if err != nil {
			dealRequestError(router, err)
			return
		}
		if groupMemberAdmin.MemberName != "" {
			adminName = groupMemberAdmin.MemberName
		}
	}
	MessageContentLen := len(messageContent) - 1
	for i := MessageContentLen; i >= 0; i-- {
		if strings.Contains(messageContent[i].HiddenUserId, params.UserId+",") {
			continue
		}
		vv := &dto.Msg{}
		_ = json.Unmarshal([]byte(messageContent[i].ContentStruct), vv)
		if tipsShow == 1 {
			if messageContent[i].SenderUserId != robotId && messageContent[i].CurrentStatus == 1 {
				tipsIsShow = 1
			}
		}
		if vv.ObjectName == "RC:InfoNtf" && strings.Contains(vv.Content, initParam.ServiceText) {
			continue
		}
		messageContent[i].Content = *vv
		// 发送者
		if messageContent[i].SenderUserId == params.UserId {
			messageContent[i].MessageDirection = 1
		} else {
			messageContent[i].MessageDirection = 2
		}
		if messageContent[i].SenderUserId != robotId {
			messageContent[i].SenderUserId = initParam.CsTarget + messageContent[i].SenderUserId
		}
		if messageContent[i].Content.Content == initParam.TimeBlockMsg {
			messageContent[i].Content.Style = "partition"
		}
		messageContentNew = append(messageContentNew, dto.MessageContent{
			MessageType:      messageContent[i].MessageType,
			Content:          messageContent[i].Content,
			SenderUserId:     messageContent[i].SenderUserId,
			TargetId:         messageContent[i].TargetId,
			SentTime:         messageContent[i].SentTime,
			ReceivedTime:     messageContent[i].ReceivedTime,
			MessageUId:       messageContent[i].MessageUId,
			MessageDirection: messageContent[i].MessageDirection,
		})
	}
	if tipsIsShow == 1 && adminName != "" {
		messageContentNew = append(messageContentNew, dto.MessageContent{
			MessageType: "RC:InfoNtf",
			Content: dto.Msg{
				Content: initParam.TimeBlockMsg,
				Style:   "partition",
			},
			SenderUserId:     robotId,
			TargetId:         params.GroupId,
			SentTime:         0,
			ReceivedTime:     0,
			MessageUId:       "",
			MessageDirection: 2,
		})
		messageContentNew = append(messageContentNew, dto.MessageContent{
			MessageType: "RC:InfoNtf",
			Content: dto.Msg{
				Content: adminName + " " + initParam.ServiceText,
			},
			SenderUserId:     robotId,
			TargetId:         params.GroupId,
			SentTime:         0,
			ReceivedTime:     0,
			MessageUId:       "",
			MessageDirection: 2,
		})
	}
	responseData := dto.MessageContentList{
		Page: dto.Page{
			PageNum:  params.PageNum,
			PageSize: params.PageSize,
			Total:    count,
		},
		MessageContent: messageContentNew,
	}
	middleware.ResponseSuccess(router, responseData)
}

// @Summary 邀请信息，转接信息展示
// @Description 消息content里面有特殊消息（style：确认消息 question；普通消息 talk 或为空字符串；合并消息 merge），这种情况下，特殊信息存在 extra 字段
// @Tags 会话
// @ID   /invitationmessages
// @Accept  json
// @Produce  json
// @Param polygon body dto.MsgConfirm true "body"
// @Success 200 {object} middleware.Response{data=dto.ChatMessagePage} "success"
// @Router /invitationmessages [post]
func (c *ChatMessageController) invitationMessages(router *gin.Context) {
	params := &dto.MsgConfirm{}
	if err := params.BindingParams(router); err != nil {
		middleware.ResponseError(router, middleware.PARMAS_ERROR_CODE, err)
		return
	}
	//
	ChatMessagePage, err := messageService.MessagesInvitation(router, BusinessDB, params.MsgUid)
	if err != nil {
		dealRequestError(router, err)
		return
	}
	vv := &dto.Msg{}
	_ = json.Unmarshal([]byte(ChatMessagePage.ContentText), vv)
	contentStruct := dto.Msg{
		MessageType: ChatMessagePage.ObjectName,
		Content:     vv.Content,
		Links:       vv.Links,
		Members:     vv.Members,
		Style:       vv.Style,
		Extra:       vv.Extra,
		ObjectName:  ChatMessagePage.ObjectName,
		ChatType:    vv.ChatType,
		ImageUri:    vv.ImageUri,
		H:           vv.H,
		W:           vv.W,
		RemoteUrl:   vv.RemoteUrl,
		Duration:    vv.Duration,
		Name:        vv.Name,
		FileUrl:     vv.FileUrl,
		Size:        vv.Size,
		Type:        vv.Type,
	}
	ChatMessagePage.ContentStruct = contentStruct
	tt, err := parseWithLocation("Asia/Shanghai", ChatMessagePage.CreateTime)
	if err != nil {
		middleware.ResponseError(router, middleware.INTERNAL_ERROR_CODE, err)
		return
	}
	ChatMessagePage.UnixTime = gconv.Int(tt.Unix()) * 1000
	responseData := ChatMessagePage
	middleware.ResponseSuccess(router, responseData)
}

// @Summary 消息转发,聊天上传
// @Description 该接口供融云调用 https://docs.rongcloud.cn/v4/views/im/noui/guide/private/msgmanage/sync/serverapi.html
// @Tags 会话
// @ID   /syncmessage
// @Accept  json
// @Produce  json
// @Param polygon body dto.ChatMessage true "body"
// @Success 200 {object} middleware.Response{} "success"
// @Router /syncmessage [post]
func (c *ChatMessageController) synchronizeMessages(router *gin.Context) {
	params := &dto.ChatMessage{}
	if err := params.BindingParams(router); err != nil {
		middleware.ResponseError(router, middleware.PARMAS_ERROR_CODE, err)
		return
	}

	// 过滤掉特殊消息
	if params.ObjectName == initParam.ChatMsgSrs {
		middleware.ResponseSuccess(router, gin.H{"msg": initParam.DealSuccessText})
		return
	}

	// msg内容
	body := []byte(params.Content)
	public.ContextNotice(router, "rongyun==>", map[string]interface{}{
		"title": router.Request.URL,
		"form":  router.Request.Form,
	})
	msg := dto.Msg{}
	if err := json.Unmarshal(body, &msg); err != nil {
		middleware.ResponseError(router, middleware.PARMAS_ERROR_CODE, err)
		return
	}

	// 过滤掉功能性消息
	if msg.ObjectName == initParam.ChatMsgInfo && msg.Content == "" {
		middleware.ResponseSuccess(router, gin.H{"msg": initParam.DealSuccessText})
		return
	}

	// 改成用数据库做判断，有则返回不处理
	chatMsgHave, err := messageService.MessageByUid(router, BusinessDB, params.MsgUId)
	if err != nil {
		if !errors.Is(err, gorm.ErrRecordNotFound) {
			middleware.ResponseError(router, middleware.USER_NOT_EXIST, err)
			return
		}
	}
	if chatMsgHave.MsgUId != "" {
		middleware.ResponseSuccess(router, gin.H{"msg": initParam.DealSuccessText})
		return
	}

	// 内容字符处理
	msg.Content = public.Utf8mb4FiltrationStar(msg.Content)
	content, err := json.Marshal(msg)
	if err != nil {
		middleware.ResponseError(router, middleware.INTERNAL_ERROR_CODE, err)
		return
	}
	contentText := string(content)
	contentText = public.Utf8mb4FiltrationStar(contentText)

	// 该聊天是客服发送或是客户发送；chatType 1 客户；2 客服
	chatType := 0
	if strings.Contains(params.FromUserID, initParam.CTarget) {
		chatType = 1
		params.FromUserID = strings.Replace(params.FromUserID, initParam.CTarget, "", -1)
	}
	if strings.Contains(params.FromUserID, initParam.CsTarget) {
		chatType = 2
		params.FromUserID = strings.Replace(params.FromUserID, initParam.CsTarget, "", -1)
	}

	// 群信息查询
	groupId := params.ToUserID
	channelType := ""
	group, err := groupService.Group(router, BusinessDB, groupId)
	if err != nil {
		dealRequestError(router, err)
		return
	}
	if group.OtherUserId > 0 {
		channelType = "PRIVATE"
	} else {
		channelType = "GROUP"
	}

	// 清除旧的timeBlockMsg数据
	if msg.Content == initParam.TimeBlockMsg {
		err = messageService.DeleteMessageTimeBlock(router, BusinessDB, groupId)
		if err != nil {
			middleware.ResponseError(router, middleware.INTERNAL_ERROR_CODE, err)
			return
		}
	}

	// 隐藏转接消息
	hiddenUserId := ""
	//if strings.Contains(msg.Content, initParam.TransMessageText) && msg.Extra != "" {
	//	hiddenUserId = hiddenUserId + params.FromUserID + ","
	//}

	// 插入消息
	groupChatMessage := &models.WkbGroupChatMessage{
		GroupId:       groupId,
		FromUserID:    params.FromUserID,
		ToUserID:      groupId,
		ObjectName:    params.ObjectName,
		ContentText:   contentText, //发送过来的 json 内容
		Extra:         msg.Extra,
		ChannelType:   channelType,
		MsgTimestamp:  params.MsgTimestamp,
		MsgUId:        params.MsgUId,
		SensitiveType: params.SensitiveType,
		Source:        params.Source,
		Status:        1,
		Content:       msg.Content, //内容
		ImageUri:      msg.ImageUri,
		H:             msg.H,
		W:             msg.W,
		RemoteUrl:     msg.RemoteUrl,
		Duration:      msg.Duration,
		FileUrl:       msg.FileUrl,
		Name:          msg.Name,
		Size:          msg.Size,
		Type:          msg.Type,
		HiddenUserId:  hiddenUserId,
		CurrentStatus: 1,
	}
	newId, newTime, err := messageService.CreateMessage(router, BusinessDB, groupChatMessage)
	if err != nil {
		middleware.ResponseError(router, middleware.INTERNAL_ERROR_CODE, err)
		return
	}

	// 修改最新的id及时间
	err = groupService.UpdateGroupLastChat(router, BusinessDB, groupId, newId, params.FromUserID, params.ObjectName, contentText, newTime)
	if err != nil {
		middleware.ResponseError(router, middleware.INTERNAL_ERROR_CODE, errors.New("ModifyGroupState failed "+err.Error()))
		return
	}

	// 私聊
	if group.OtherUserId > 0 {
		msg.ChatType = "private"
		otherUserId := 0
		if group.UserId == gconv.Int(params.FromUserID) {
			otherUserId = group.OtherUserId
		} else {
			otherUserId = group.UserId
		}

		// 转接消息处理
		transMessage(msg, groupId, gconv.String(otherUserId), params.MsgUId)

		// 邀请消息处理
		invitationMessage(msg, groupId, gconv.String(otherUserId), params.MsgUId)

	} else
	{
		// 获取群 缓存
		groupCache := getGroupMsg(router, groupId)
		if groupCache.GroupID == "" {
			middleware.ResponseError(router, middleware.INTERNAL_ERROR_CODE, errors.New(initParam.ErrorGroupCache))
			return
		}

		// 获取群聊【成员，包括客户、客服、管理、机器人】缓存
		groupMemberCache := getGroupMember(router, groupId)
		if len(groupMemberCache) == 0 {
			middleware.ResponseError(router, middleware.INTERNAL_ERROR_CODE, errors.New(initParam.ErrorGroupMemberCache))
			return
		}
		// 是否有管理标志,包括客服、管理
		groupHaveCs := 0
		// 查询当前发送的用户身份，是 客户 还是 客服 （客户：user.MemberType = 0；客服：user.MemberType ！= 0 != 1；）
		adminUid := 0
		for _, v := range groupMemberCache {
			if v.MemberType > 1 {
				groupHaveCs = 1
			}
			if v.MemberType == 2 {
				adminUid = v.UserID
			}
		}

		// 不是机器人发送的消息
		if !strings.Contains(params.FromUserID, "robot") {

			//以群id加 _customer 为键名
			cacheKey := groupId + "_customer"

			// 系统回复设置
			replySetting, err := serviceService.ReplySetting(router, BusinessDB)
			if err != nil {
				dealRequestError(router, err)
				return
			}

			// 客户发送的内容
			if chatType == 1 {

				// 清除客服相关缓存
				clearCsCache(router, groupId, adminUid)

				//群状态恢复为正在进行中
				err := groupService.UpdateGroupState(router, BusinessDB, groupId, 1)
				if err != nil {
					middleware.ResponseError(router, middleware.INTERNAL_ERROR_CODE, err)
					return
				}

				// 查找所在群的机器人（先查缓存）
				fromUserId := ""
				if cacheMap.GroupRobot.Get(cacheKey) != nil {
					fromUserId = cacheMap.GroupRobot.Get(cacheKey).(string)
				} else {
					groupRobot, err := groupService.GroupRobot(router, BusinessDB, groupId)
					if err != nil {
						dealRequestError(router, err)
						return
					}
					fromUserId = initParam.RobotTarget + gconv.String(groupRobot.ID)
					cacheMap.GroupRobot.Set(cacheKey, fromUserId)
				}

				// 系统回复设置-客服无应答状态
				if replySetting.CustomerServiceFlag == 1 {
					setCustomerServiceCache(cacheKey, fromUserId, groupId, replySetting)
				}

				// 关键词
				keyWord, err := serviceService.KeyWordListWord(router, BusinessDB)
				if err != nil {
					dealRequestError(router, err)
					return
				}
				jumpGroupId := ""
				skillGroupId := 0
				sendAnswerText := ""
				for _, v := range keyWord {
					//跳转
					if v.DataFlag == 1 && jumpGroupId == "" && strings.Contains(strings.ToLower(msg.Content), strings.ToLower(v.Keyword)) {
						jumpGroupId = v.GroupId
					}
					//回复
					if v.DataFlag == 2 && sendAnswerText == "" && strings.Contains(strings.ToLower(msg.Content), strings.ToLower(v.Keyword)) {
						sendAnswerText = v.AnswerText
					}
				}
				// 如果没有群【客服，管理】，且关键字没有匹配到，则匹配到超级管理员来接入群聊
				if groupHaveCs == 0 && jumpGroupId == "" {
					skillGroupId = 1
				}
				// 第一次需求：如果有群【客服，管理】，且关键字有匹配到，则匹配到对应管理员来接入群聊，且对应的管理组不是管理员组
				// 第二次需求：不再允许用户通过点击 菜单切换技能组
				if groupHaveCs == 0 && jumpGroupId != "" {
					skillGroupId = gconv.Int(jumpGroupId)
				}
				//拉入管理员
				if skillGroupId > 0 {
					lastUserId := redisModules.RedisLastAccessSkillGroupId("LastAccessSkillGroupId_"+gconv.String(skillGroupId), 0)
					findSuperUser, err := serviceService.SkillGroup(router, BusinessDB, skillGroupId, lastUserId)
					if err != nil {
						if errors.Is(err, gorm.ErrRecordNotFound) {
							toBeAllocatedCache := cacheMap.ToBeAllocated.Get(skillGroupId)
							toBeAllocated := make([]models.WkbGroup, 0)
							addAllocated := 1
							if toBeAllocatedCache != nil {
								toBeAllocated = toBeAllocatedCache.([]models.WkbGroup)
								for _, v := range toBeAllocated {
									if v.GroupID == groupId && v.UserId == gconv.Int(params.FromUserID) {
										addAllocated = 0
									}
								}
							}
							if addAllocated == 1 {
								toBeAllocated = append(toBeAllocated, models.WkbGroup{
									GroupID: groupId,
									Name:    groupCache.Name,
									UserId:  gconv.Int(params.FromUserID),
								})
								cacheMap.ToBeAllocated.Set(skillGroupId, toBeAllocated)
							}
						} else {
							middleware.ResponseError(router, middleware.INTERNAL_ERROR_CODE, err)
							return
						}
					} else {
						//引入客服 为客户服务
						err = joinGroup(router, 2, 1, dto.UserDetail{
							UserId:   findSuperUser.UserId,
							Nickname: findSuperUser.Nickname,
							Avatar:   findSuperUser.Avatar,
						}, models.WkbGroup{
							GroupID: groupId,
							Name:    groupCache.Name,
						}, skillGroupId)
						if err != nil {
							middleware.ResponseError(router, middleware.INTERNAL_ERROR_CODE, err)
							return
						}
						//加入缓存
						//cacheMap.LastAccessSkillGroupCS.Set(skillGroupId, findSuperUser.UserId)
						redisModules.RedisLastAccessSkillGroupId("LastAccessSkillGroupId_"+gconv.String(skillGroupId), findSuperUser.UserId)
					}
				} else {
					//判断当群内已经有群主时，发送一句话
					hasBeenSent := redisModules.RedisSendIntroductionText("get", "SendIntroductionText_"+groupId, 0)
					if hasBeenSent == 0 {
						groupMemberAdmin, err := groupService.GroupMemberAdmin(router, BusinessDB, groupId)
						if err != nil {
							dealRequestError(router, err)
							return
						}
						err = send(dto.Group{
							GroupId: groupId,
							Msg:     groupMemberAdmin.MemberName,
							MsgType: 4, //
						})
						if err != nil {
							middleware.ResponseError(router, middleware.INTERNAL_ERROR_CODE, err)
							return
						}
					}
				}
				//发送关键词触发语
				if sendAnswerText != "" {
					err = send(dto.Group{
						GroupId: groupId,
						Msg:     sendAnswerText,
						MsgType: 12, //
					})
					if err != nil {
						middleware.ResponseError(router, middleware.INTERNAL_ERROR_CODE, err)
						return
					}
				}
			}

			// 如果是客服发送的内容，则清除客户相关缓存
			if chatType > 1 {
				clearCCache(router, groupId, params.FromUserID)
				if replySetting.CustomerFlag == 1 {
					//以群id加 _customer 为键名
					key := groupId + "_customerService"
					fromUserId := ""
					//查找所在群的机器人（先查缓存）
					if cacheMap.GroupRobot.Get(key) != nil {
						fromUserId = cacheMap.GroupRobot.Get(key).(string)
					} else {
						groupRobot, err := groupService.GroupRobot(router, BusinessDB, groupId)
						if err != nil {
							dealRequestError(router, err)
							return
						}
						fromUserId = initParam.RobotTarget + gconv.String(groupRobot.ID)
						cacheMap.GroupRobot.Set(key, fromUserId)
					}
					timeout := gconv.String(time.Now().Add(time.Duration(replySetting.CustomerTimeout) * time.Minute).Unix())
					if taskMap.M.Get(key) == nil {
						//构造发送结构
						s := taskMap.SendMap{
							FromUserID: gtype.NewString(fromUserId),
							ToUserID:   gtype.NewString(groupId),
							Content:    gtype.NewString(replySetting.CustomerText),
							ChatType:   gtype.NewString("group"),
							TimeStamp:  gtype.NewInt(gconv.Int(timeout)),
							Type:       gtype.NewString("sendToC"),
						}
						taskMap.M.Set(key, s)
					} else {
						sMap := taskMap.M.Get(key).(taskMap.SendMap)
						//最新的设置时间比旧的小，采用新的
						if sMap.TimeStamp.Val() > gconv.Int(timeout) {
							s := taskMap.SendMap{
								FromUserID: gtype.NewString(fromUserId),
								ToUserID:   gtype.NewString(groupId),
								Content:    gtype.NewString(replySetting.CustomerText),
								ChatType:   gtype.NewString("group"),
								TimeStamp:  gtype.NewInt(gconv.Int(timeout)),
								Type:       gtype.NewString("sendToC"),
							}
							taskMap.M.Set(key, s)
						}
					}
				}
			}

		} else {
			if msg.ObjectName == initParam.ChatMsgTxt {
				key := groupId + "_customer"
				if taskMap.M.Get(key) != nil {
					taskMap.M.Remove(key)
				}
			}
			if msg.ObjectName == initParam.ChatMsgInfo && strings.Contains(msg.Content, initParam.TimeoutText) {
				customerServiceHidden := ""
				for _, v := range groupMemberCache {
					if v.MemberType > 2 {
						customerServiceHidden = customerServiceHidden + gconv.String(v.UserID) + ","
					}
				}
				if customerServiceHidden != "" {
					err = messageService.UpdateMessageHiddenUserId(router, BusinessDB, params.MsgUId, customerServiceHidden)
					if err != nil {
						middleware.ResponseError(router, middleware.INTERNAL_ERROR_CODE, err)
						return
					}
				}
			}
			if msg.ObjectName == initParam.ChatMsgInfo && strings.Contains(msg.Content, initParam.TransRefuseText) {
				customerServiceHidden := ""
				for _, v := range groupMemberCache {
					if v.MemberType > 2 {
						customerServiceHidden = customerServiceHidden + gconv.String(v.UserID) + ","
					}
				}
				if customerServiceHidden != "" {
					err = messageService.UpdateMessageHiddenUserId(router, BusinessDB, params.MsgUId, customerServiceHidden)
					if err != nil {
						middleware.ResponseError(router, middleware.INTERNAL_ERROR_CODE, err)
						return
					}
				}
			}
			if msg.ObjectName == initParam.ChatMsgInfo && strings.Contains(msg.Content, initParam.TimeoutText) {
				customerServiceHidden := ""
				for _, v := range groupMemberCache {
					if v.MemberType == 0 {
						customerServiceHidden = customerServiceHidden + gconv.String(v.UserID) + ","
					}
				}
				if customerServiceHidden != "" {
					err = messageService.UpdateMessageHiddenUserId(router, BusinessDB, params.MsgUId, customerServiceHidden)
					if err != nil {
						middleware.ResponseError(router, middleware.INTERNAL_ERROR_CODE, err)
						return
					}
				}
			}
		}
		redisModules.RedisSendGroupWelcomeText("set", "SendGroupWelcomeText_"+groupId, 1)
	}
	//修改列表缓存
	updateRedis(router, groupId)
	//
	middleware.ResponseSuccess(router, gin.H{"msg": initParam.DealSuccessText})

}

// @Summary 会话转发
// @Description
// @Tags 会话
// @ID   /forwardmessages
// @Accept  json
// @Produce  json
// @Param polygon body dto.MsgList true "body"
// @Success 200 {object} middleware.Response{} "success"
// @Router /forwardmessages [post]
func (c *ChatMessageController) forwardMessages(router *gin.Context) {
	params := &dto.MsgList{}
	if err := params.BindingParams(router); err != nil {
		middleware.ResponseError(router, middleware.PARMAS_ERROR_CODE, err)
		return
	}
	//发送一条特殊消息
	//雪花id
	groupId, err := makePrivateGroupBeforeTalk(router, params.FromUserID, params.ToUserID)
	if err != nil {
		middleware.ResponseError(router, middleware.INTERNAL_ERROR_CODE, err)
		return
	}
	extra := public.GenID()
	err = send(dto.Group{
		UserId:  params.FromUserID,
		GroupId: groupId,
		Msg:     initParam.MergeText,
		MsgType: 13, //
		Extra:   extra,
	})
	if err != nil {
		middleware.ResponseError(router, middleware.INTERNAL_ERROR_CODE, err)
		return
	}
	//合并另存，创建一条合并消息
	msgList := make([]dto.Msg, 0)
	for _, v := range params.MsgUidList {
		if len(v.Links) == 0 {
			v.Links = make([]map[string]string, 0)
		}
		msgList = append(msgList, v)
	}
	mergeStr, err := json.Marshal(msgList)
	if err != nil {
		middleware.ResponseError(router, middleware.INTERNAL_ERROR_CODE, err)
		return
	}
	err = messageService.CreateMergeMessage(router, BusinessDB, &models.WkbImMergeMessage{
		MergeId: extra,
		Content: string(mergeStr),
	})
	if err != nil {
		middleware.ResponseError(router, middleware.INTERNAL_ERROR_CODE, err)
		return
	}

	middleware.ResponseSuccess(router, gin.H{"msg": initParam.DealSuccessText, "id": extra})
}

// @Summary 会话转接转出
// @Description 调用通讯录接口，发送一个自定义消息给到对方；需要传值 GroupId，UserId，OtherUserId
// @Tags 会话
// @ID   /transfermessagesout
// @Accept  json
// @Produce  json
// @Param polygon body dto.Group true "body"
// @Success 200 {object} middleware.Response{} "success"
// @Router /transfermessagesout [post]
func (c *ChatMessageController) transferMessagesOut(router *gin.Context) {
	params := &dto.Group{}
	if err := params.BindingParams(router); err != nil {
		middleware.ResponseError(router, middleware.PARMAS_ERROR_CODE, err)
		return
	}
	//发送转接询问 【框】
	err := send(dto.Group{
		GroupId:     params.GroupId,
		UserId:      params.UserId,
		OtherUserId: params.OtherUserId,
		MsgType:     9, //
	})
	if err != nil {
		middleware.ResponseError(router, middleware.INTERNAL_ERROR_CODE, err)
		return
	}
	//发送【正在转接】状态 【提示】 告知用户
	err = send(dto.Group{
		GroupId: params.GroupId,
		MsgType: 14, //
	})
	if err != nil {
		middleware.ResponseError(router, middleware.INTERNAL_ERROR_CODE, err)
		return
	}
	middleware.ResponseSuccess(router, gin.H{"msg": initParam.DealSuccessText})
}

// @Summary 会话转接转入
// @Description confirm 是否接入 0 否 1 是；extra 额外消息，接入时为 要接入的群id；msgUid 融云消息id，唯一；userId
// @Tags 会话
// @ID   /transfermessagesin
// @Accept  json
// @Produce  json
// @Param polygon body dto.MsgConfirm true "body"
// @Success 200 {object} middleware.Response{} "success"
// @Router /transfermessagesin [post]
func (c *ChatMessageController) transferMessagesIn(router *gin.Context) {
	params := &dto.MsgConfirm{}
	if err := params.BindingParams(router); err != nil {
		middleware.ResponseError(router, middleware.PARMAS_ERROR_CODE, err)
		return
	}
	//确认消息，将消息原来的 "style":"question" 替换为 "style":"answer"
	//messageUid, err := messageService.MessageByUid(router, BusinessDB, params.MsgUid)
	//if err != nil {
	//	middleware.ResponseError(router, middleware.INTERNAL_ERROR_CODE, err)
	//	return
	//}
	//groupId 当前的私聊群
	//params.UserId 当前的操作者（被邀请人 或者 被转接人）
	//params.Extra 要去到或者拒绝的客户群
	//groupId := messageUid.GroupId
	switch params.Confirm {
	case 1:
		//接受转接
		err := confirmChatMessage(router, 1, params.MsgUid, params.UserId, 1, params.Extra)
		if err != nil {
			middleware.ResponseError(router, middleware.INTERNAL_ERROR_CODE, err)
			return
		}
		//在群内发送 我进来了
		groupCache := getGroupMsg(router, params.Extra)
		if groupCache.GroupID == "" {
			middleware.ResponseError(router, middleware.INTERNAL_ERROR_CODE, errors.New(initParam.ErrorGroupCache))
			return
		}
		csUser, err := customerServiceService.CsUser(router, BusinessDB, params.UserId)
		if err != nil {
			dealRequestError(router, err)
			return
		}
		//判断是否已经在群聊
		groupMemberCs, err := groupService.GroupMemberCs(router, InstanceDB, params.Extra)
		if err != nil {
			dealRequestError(router, err)
			return
		}
		inGroup := 0
		for _, v := range groupMemberCs {
			if v.UserID == params.UserId {
				inGroup = 1
			}
		}
		//拉人入群
		if inGroup == 0 {
			err = joinGroup(router, 2, 0, csUser, groupCache, 0)
			if err != nil {
				middleware.ResponseError(router, middleware.PARMAS_ERROR_CODE, err)
				return
			}
		}
		break
	case 2:
		err := confirmChatMessage(router, 1, params.MsgUid, params.UserId, 2, params.Extra)
		if err != nil {
			middleware.ResponseError(router, middleware.INTERNAL_ERROR_CODE, err)
			return
		}
		break
	case 3:
		//给 邀请人 发送同意 answer 1 接收 2 拒绝
		err := confirmChatMessage(router, 2, params.MsgUid, params.UserId, 1, params.Extra)
		if err != nil {
			middleware.ResponseError(router, middleware.INTERNAL_ERROR_CODE, err)
			return
		}
		//在群内发送 我进来了
		groupCache := getGroupMsg(router, params.Extra)
		if groupCache.GroupID == "" {
			middleware.ResponseError(router, middleware.INTERNAL_ERROR_CODE, errors.New(initParam.ErrorGroupCache))
			return
		}
		csUser, err := customerServiceService.CsUser(router, BusinessDB, params.UserId)
		if err != nil {
			dealRequestError(router, err)
			return
		}
		//判断是否已经在群聊
		groupMember, err := groupService.GroupMember(router, InstanceDB, params.Extra)
		if err != nil {
			dealRequestError(router, err)
			return
		}
		inGroup := 0
		for _, v := range groupMember {
			if v.UserID == params.UserId {
				inGroup = 1
			}
		}
		//拉人入群
		if inGroup == 0 {
			err = joinGroup(router, 1, 0, csUser, groupCache, 0)
			if err != nil {
				middleware.ResponseError(router, middleware.PARMAS_ERROR_CODE, err)
				return
			}
			invitationMemberCache := cacheMap.InvitationMember.Get(params.Extra)
			if invitationMemberCache != nil {
				invitationMemberNew := make([]string, 0)
				invitationMember := invitationMemberCache.([]string)
				for _, v := range invitationMember {
					if v != gconv.String(params.UserId) {
						invitationMemberNew = append(invitationMemberNew, v)
						cacheMap.InvitationMemberDetail.Set(params.Extra+"_"+v, time.Now().Add(initParam.InvitationTimeOut).Unix())
					}
				}
				if len(invitationMemberNew) > 0 {
					cacheMap.InvitationMember.Set(params.Extra, invitationMemberNew)
				} else {
					cacheMap.InvitationMember.Remove(params.Extra)
				}
			}
		}
		break
	case 4:
		//answer 1 接收 2 拒绝
		err := confirmChatMessage(router, 2, params.MsgUid, params.UserId, 2, params.Extra)
		if err != nil {
			middleware.ResponseError(router, middleware.INTERNAL_ERROR_CODE, err)
			return
		}
		invitationMemberCache := cacheMap.InvitationMember.Get(params.Extra)
		if invitationMemberCache != nil {
			invitationMemberNew := make([]string, 0)
			invitationMember := invitationMemberCache.([]string)
			for _, v := range invitationMember {
				if v != gconv.String(params.UserId) {
					invitationMemberNew = append(invitationMemberNew, v)
					cacheMap.InvitationMemberDetail.Set(params.Extra+"_"+v, time.Now().Add(initParam.InvitationTimeOut).Unix())
				}
			}
			if len(invitationMemberNew) > 0 {
				cacheMap.InvitationMember.Set(params.Extra, invitationMemberNew)
			} else {
				cacheMap.InvitationMember.Remove(params.Extra)
			}
		}
		break
	default:
		break
	}
	updateRedis(router, params.Extra)
	if params.Confirm == 1 || params.Confirm == 3 {
		middleware.ResponseSuccess(router, gin.H{"msg": initParam.DealSuccessText, "groupId": params.Extra})
	} else {
		middleware.ResponseSuccess(router, nil, 401)
	}
}

// @Summary 合并消息展示
// @Description
// @Tags 会话
// @ID   /mergemessages
// @Accept  json
// @Produce  json
// @Param polygon body dto.Common true "body"
// @Success 200 {object} middleware.Response{data=[]dto.Msg} "success"
// @Router /mergemessages [post]
func (c *ChatMessageController) mergeMessages(router *gin.Context) {
	params := &dto.Common{}
	if err := params.BindingParams(router); err != nil {
		middleware.ResponseError(router, middleware.PARMAS_ERROR_CODE, err)
		return
	}
	ChatMessagePage, err := messageService.MergeMessage(router, BusinessDB, params.Id)
	if err != nil {
		dealRequestError(router, err)
		return
	}
	if ChatMessagePage.MergeId == "" {
		responseData := dto.NullComeBack{
			Page: dto.Page{},
			List: make([]string, 0),
		}
		middleware.ResponseSuccess(router, responseData)
		return
	}
	mergeMessage := &[]dto.Msg{}
	err = json.Unmarshal([]byte(ChatMessagePage.Content), mergeMessage)
	if err != nil {
		middleware.ResponseError(router, middleware.INTERNAL_ERROR_CODE, err)
		return
	}
	responseData := mergeMessage
	middleware.ResponseSuccess(router, responseData)
}

// @Summary 客户重新进入聊天
// @Description 只需要传递 GroupId
// @Tags 会话
// @ID   /customercoming
// @Accept  json
// @Produce  json
// @Param polygon body dto.Group true "body"
// @Success 200 {object} middleware.Response{} "success"
// @Router /customercoming [post]
func (c *ChatMessageController) CustomerComing(router *gin.Context) {
	params := &dto.Group{}
	if err := params.BindingParams(router); err != nil {
		middleware.ResponseError(router, middleware.PARMAS_ERROR_CODE, err)
		return
	}
	//判断是否需要发送客户重新进入的欢迎语
	//isSend := 0
	hasBeenSent := redisModules.RedisSendGroupWelcomeText("get", "SendGroupWelcomeText_"+params.GroupId, 0)
	if hasBeenSent == 0 {
		//发送入群提示语
		groupCache := getGroupMsg(router, params.GroupId)
		if groupCache.GroupID == "" {
			middleware.ResponseError(router, middleware.INTERNAL_ERROR_CODE, errors.New(initParam.ErrorGroupCache))
			return
		}
		chatMsg, err := messageService.MessageByGroupId(router, BusinessDB, params.GroupId)
		if err != nil {
			if !errors.Is(err, gorm.ErrRecordNotFound) {
				middleware.ResponseError(router, middleware.INTERNAL_ERROR_CODE, err)
				return
			}
		}
		if chatMsg.GroupId != "" {
			err = send(dto.Group{
				GroupId: params.GroupId,
				MsgType: 16, //
			})
			if err != nil {
				middleware.ResponseError(router, middleware.INTERNAL_ERROR_CODE, err)
				return
			}
		}
		err = send(dto.Group{
			Id:      groupCache.ID,
			GroupId: params.GroupId,
			MsgType: 1, //
		})
		if err != nil {
			middleware.ResponseError(router, middleware.INTERNAL_ERROR_CODE, err)
			return
		}
		//redisSendIntroductionText("set", "SendIntroductionText_"+params.GroupId, 0)
	}
	redisModules.RedisSendGroupWelcomeText("set", "SendGroupWelcomeText_"+params.GroupId, 1)
	middleware.ResponseSuccess(router, gin.H{"msg": initParam.DealSuccessText})
}
